import { Inject, Injectable } from '@nestjs/common';
import * as bcrypt from 'bcrypt';
import { UserService } from '../user/user.service';
import { User } from '../user/entities/user.entity';
import { JwtService } from '@nestjs/jwt';
import { ConfigService } from '@nestjs/config';
import { CACHE_MANAGER, Cache } from '@nestjs/cache-manager';
import { REDIS_KEY } from 'src/common/redis/redisKey';
import { CreateUserInput, LoginUserInput } from '../user/dto/inputDto';
@Injectable()
export class AuthService {
  constructor(
    @Inject(CACHE_MANAGER) private cacheManager: Cache,
    private readonly userService: UserService,
    private readonly jwtService: JwtService,
    private readonly configService: ConfigService,
  ) { }

  async validateUser(loginUserInput: LoginUserInput) {
    const { email, password } = loginUserInput;
    const user = await this.userService.findWhereOne({ $or: [{ email: email }, { name: email }] });
    const isMatch = await bcrypt.compare(password, user?.password);

    if (user && isMatch) {
      return user;
    }

    return null;
  }

  async signup(payload: CreateUserInput) {
    const user = await this.userService.findWhereOne({ $or: [{ email: payload.email }, { name: payload.email }] });
    if (user) {
      throw new Error('User already exists, login instead');
    }
    return this.userService.createUserInfo(payload);
  }

  async login(user: User) {
    const token = this.jwtService.sign(
      {
        email: user.email,
        name: user.name,
        sub: user._id,
      },
      {
        secret: this.configService.get<string>('JWT_SECRET'),
      },
    );

    const expires = 1000 * 60 * 60 * 24;
    const key = REDIS_KEY.USER_TOKEN(user._id.toString());
    await this.cacheManager.set(key, token, expires);

    const resultUser = { user, token, expires };
    return resultUser;
  }
}
